package com.heima.wemedia.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.common.constants.WmNewsMessageConstants;
import com.heima.model.common.dtos.PageResponseResult;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.wemedia.dto.WmNewsDto;
import com.heima.model.wemedia.dto.WmNewsPageReqDto;
import com.heima.model.wemedia.pojos.WmMaterial;
import com.heima.model.wemedia.pojos.WmNews;
import com.heima.model.wemedia.pojos.WmNewsMaterial;
import com.heima.utils.thread.WmTheadLocalUtil;
import com.heima.wemedia.mapper.WmMaterialMapper;
import com.heima.wemedia.mapper.WmNewsMaterialMapper;
import com.heima.wemedia.service.*;
import com.heima.wemedia.mapper.WmNewsMapper;
import lombok.extern.slf4j.Slf4j;
import net.sourceforge.tess4j.TesseractException;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author 石头
 * @description 针对表【wm_news(自媒体图文内容信息表)】的数据库操作Service实现
 * @createDate 2022-06-14 19:20:15
 */
@Service
@Slf4j
public class mNewsServiceImpl extends ServiceImpl<WmNewsMapper, WmNews>
        implements WmNewsService {

    @Resource
    private WmNewsMapper wmNewsMapper;

    @Resource
    private WmNewsMaterialService wmNewsMaterialService;


    @Resource
    private WmMaterialMapper wmMaterialMapper;

    @Resource
    private WmNewsMaterialMapper wmNewsMaterialMapper;

    /**
     * 查询自媒体文章
     *
     * @param wmNewsPageReqDto
     * @return
     */
    @Override
    public ResponseResult newList(WmNewsPageReqDto wmNewsPageReqDto) {
        Integer size = wmNewsPageReqDto.getSize();
        Integer page = wmNewsPageReqDto.getPage();
        String keyword = wmNewsPageReqDto.getKeyword();
        Short status = wmNewsPageReqDto.getStatus();
        Date beginPubdate = wmNewsPageReqDto.getBeginPubdate();
        Date endPubdate = wmNewsPageReqDto.getEndPubdate();
        Integer channelId = wmNewsPageReqDto.getChannelId();
        if (size <= 0) {
            size = 10;
        }
        if (page <= 0) {
            page = 1;
        }

        // 分页查询
        IPage wmNewsPage = new Page(page, size);
        // 查询条件构造
        LambdaQueryWrapper<WmNews> queryWrapper = new LambdaQueryWrapper<>();

        // 关键字模糊查询
        if (StringUtils.isNotEmpty(keyword)) {
            queryWrapper.like(WmNews::getTitle, keyword);
        }
        // 频道
        if (channelId != null) {
            queryWrapper.eq(WmNews::getChannelId, channelId);
        }
        // 文章状态发布
        if (status != null) {
            queryWrapper.eq(WmNews::getStatus, status);
        }
        // 时间差
        if (beginPubdate != null && endPubdate != null) {
            queryWrapper.between(WmNews::getCreatedTime, wmNewsPageReqDto.getBeginPubdate(), wmNewsPageReqDto.getEndPubdate());
        }

        IPage iPage = page(wmNewsPage, queryWrapper);
        // 封装数据
        ResponseResult responseResurt = new PageResponseResult(page, size, (int) iPage.getTotal());
        responseResurt.setData(iPage.getRecords());

        return responseResurt;
    }


    @Autowired
    private WmNewsTaskService wmNewsTaskService;

    /**
     * 文章发布
     *
     * @param wmNewsDto
     * @return
     */
    @Override
    public ResponseResult submit(WmNewsDto wmNewsDto) throws IOException, TesseractException {
        log.info("---文章发布---");
        // 参数不为空，标题不为空
        if (wmNewsDto == null || StringUtils.isBlank(wmNewsDto.getTitle())) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        // 对象拷贝
        WmNews wmNews = new WmNews();
        BeanUtils.copyProperties(wmNewsDto, wmNews);
        log.info("对象拷贝后 wmNews= {},", wmNews);
        // 抽取封面图片和抽取content中图片
        List<String> coverImages = wmNewsDto.getImages();
        List<String> contentImages = getContentImages(wmNewsDto);

        // 文章布局  -1类型自动处理  0 无图文章  1 单图文章  3 多图文章
        if (wmNewsDto.getType() == -1) {
            if (contentImages.size() >= 3) {
                coverImages = contentImages.stream().limit(3).collect(Collectors.toList());
                wmNews.setType(3);
            } else if (0 < contentImages.size() && contentImages.size() < 3) {
                coverImages = contentImages.stream().limit(1).collect(Collectors.toList());
                wmNews.setType(1);
            } else {
                coverImages = Collections.emptyList();
                wmNews.setType(0);
            }
        }
        // 封装封面图片数据
        if (CollectionUtils.isNotEmpty(coverImages)) {
            wmNews.setImages(StringUtils.join(coverImages, ","));
        }
        // 文章保存和修改
        newsSaveAndUpdate(wmNews);
        // 是草稿
        if (wmNewsDto.getStatus() == 0) {
            return ResponseResult.okResult(null);

        }

        // 保存封面引用关系
        savaCoverMaterialRealation(wmNews.getId(), coverImages);
        // 保存内容引用关系
        savaContentMaterialRealation(wmNews.getId(), contentImages);

        //审核文章
        //wmArticleAutoReview.autoScanWmNews(wmNews.getId());
        wmNewsTaskService.addNewsToTask(wmNews.getId(), wmNews.getPublishTime());
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    /**
     * 文章查看详情
     *
     * @param id
     * @return
     */
    @Override
    public ResponseResult getNewsById(Integer id) {
        log.info("文章查看详情");
        if (id == null || id < 0) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        WmNews wmNews = this.getById(id);
        // 文章不存在
        if (wmNews == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        return ResponseResult.okResult(wmNews);
    }

    /**
     * 文章删除
     *
     * @param id
     * @return
     */
    @Override
    public ResponseResult delNews(Integer id) {
        log.info("文章删除");
        if (id == null || id < 0) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        WmNews wmNews = this.getById(id);
        // 文章不存在
        if (wmNews == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        // 状态 0 下架  删除
        Integer status = wmNews.getStatus();
        if (status == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        // 上架状态无法删除
        if (status == 9) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEWS_PUBLISHED);
        }
        // 删除素材关系
        int delete = wmNewsMaterialMapper.delete(Wrappers.<WmNewsMaterial>lambdaQuery().eq(WmNewsMaterial::getNewsId, id));
        log.info("dalete:{}", delete);

        boolean removeById = this.removeById(id);
        log.info("removeById:{}", removeById);
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    @Resource
    private KafkaTemplate kafkaTemplate;

    /**
     * 文章上下架
     *
     * @param wmNewsDto
     * @return
     */
    @Override
    public ResponseResult downOrUp(WmNewsDto wmNewsDto) {
        log.info("上架下架开始");
        // 校验参数
        if (wmNewsDto == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        Integer enable = wmNewsDto.getEnable();
        Integer id = wmNewsDto.getId();
        if (id == null || id < 0) {
            return ResponseResult.errorResult(AppHttpCodeEnum.ERROR_ID);
        }
        if (enable == null || enable != 0 && enable != 1) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        // 修改enable 上架下架 先查询 后修改
        WmNews wmNews = this.getById(id);
        // 文章不存在
        if (wmNews == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.ESSAY_NOT_EXIST);
        }
        // 文章不是发布状态
        if (wmNews.getStatus() != 9) {
            return ResponseResult.errorResult(AppHttpCodeEnum.ARTICLE_NOT_PUBLISHED);
        }
        // 上架
        if (wmNews.getEnable() == 0) {
            wmNews.setEnable(1);
            log.info("上架下架开始");
        } else {
            // 下架
            wmNews.setEnable(0);
        }
        this.updateById(wmNews);
        //发送消息，通知article端修改文章配置
        if (wmNews.getId() != null) {
            HashMap<String, Object> map = new HashMap<>();
            map.put("articleId", wmNews.getArticleId());
            map.put("enable", wmNews.getEnable());
            kafkaTemplate.send(WmNewsMessageConstants.WM_NEWS_UP_OR_DOWN_TOPIC, JSON.toJSONString(map));
        }
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    /**
     * 保存内容引用关系
     *
     * @param newId
     * @param contentImages
     */
    private void savaContentMaterialRealation(Integer newId, List<String> contentImages) {
        // 内容图片与文章的关系
        saveCoverImagesMaterialRelation(newId, contentImages, 0);
    }

    /**
     * 保存封面引用关系
     *
     * @param newId
     * @param coverImages
     */
    private void savaCoverMaterialRealation(Integer newId, List<String> coverImages) {
        // 封面图片与文章的关系
        saveCoverImagesMaterialRelation(newId, coverImages, 1);
    }

    /**
     * 图片与文章的关系
     *
     * @param newId  文章ID
     * @param images 图片url
     * @param type   引用类型  0 内容引用  1 主图引用
     */
    private void saveCoverImagesMaterialRelation(Integer newId, List<String> images, int type) {
        // 校验图片是否存在
        if (CollectionUtils.isEmpty(images)) {
            return;
        }

        // 根据images 查询素材信息 coverImages 可能为重复图片，或者缺失图片
        // 重复图片，去重
        images = images.stream().distinct().collect(Collectors.toList());
        // 根据图片url 查询素材信息
        List<WmMaterial> wmMaterialList = wmMaterialMapper.findMeterial(images);
        log.info("根据图片路径查询素材对象= {}", wmMaterialList);

        // 判断图片是否缺失
        List<Integer> ids = wmMaterialList.stream().map(WmMaterial::getId).collect(Collectors.toList());
        log.info("ids= {}", ids);
        if (images.size() != ids.size()) {
            throw new RuntimeException("素材图片缺失");
        }
        // 保存素材和文章关系的管理关系
        wmNewsMaterialMapper.saveNewsRelation(newId, ids, type);
    }

    /**
     * 文章保存和修改
     *
     * @param wmNews
     */

    public void newsSaveAndUpdate(WmNews wmNews) {
        // 补全数据
        wmNews.setUserId(WmTheadLocalUtil.getWmUser().getApUserId());
        wmNews.setSubmitedTime(new Date());
        // 默认上架
        wmNews.setEnable(1);
        // 文章id
        Integer id = wmNews.getId();
        // 文章保存
        if (id == null) {
            // 创建时间
            wmNews.setCreatedTime(new Date());
            wmNewsMapper.insert(wmNews);
            log.info("---文章新增---");
            return;
        }

        // 文章修改  修改之前需要删除素材图片的关系，重新创建一个关系，否则会重复创建关系
        wmNewsMaterialService.remove(Wrappers.<WmNewsMaterial>lambdaQuery().eq(WmNewsMaterial::getNewsId, id));
        wmNewsMapper.updateById(wmNews);
        log.info("---文章修改---");
    }


    /**
     * 抽取content中图片
     *
     * @param wmNewsDto
     * @return
     */
    private List<String> getContentImages(WmNewsDto wmNewsDto) {
        String content = wmNewsDto.getContent();
        List<Map> maps = JSON.parseArray(content, Map.class);
        log.info("maps= {}", maps);
        // 过滤image类型 保留image,image 路径转换
        List<String> WmNewsDto = maps.stream().filter(map -> map.get("type").equals("image")).map(map -> map.get("value").toString()).collect(Collectors.toList());
        return WmNewsDto;
    }
}




